import datetime
import math
from concurrent.futures import ThreadPoolExecutor, as_completed

import holidays
import requests


def get_tdx_market_code(stock_code):
    """
    根据股票代码获取通达信市场代码
    :param stock_code: 股票代码（字符串）
    :return: 通达信市场代码（字符串）
    """
    if stock_code.startswith('6'):      # 600292 688093
        # 沪市A股
        return '1'
    elif stock_code.startswith('0'):    # 000004
        # 深市A股
        return '0'
    elif stock_code.startswith('3'):    #300884
        # 创业板
        return '0'
    else:
        return '2'  # 未知市场代码

def write_list_to_file(data_list, filename):
    """
    将列表写入文本文件，每个元素占一行。

    参数:
    data_list (list): 要写入的列表。
    filename (str): 要写入的文件名。
    """
    try:
        # 使用open()函数以写入模式打开文件
        with open(filename, 'a', encoding='utf-8') as file:
            # 遍历列表中的每个元素，并将其写入文件，每个元素后面跟一个换行符
            for item in data_list:
                file.write(f"{item}\n")
        print(f"列表已成功写入文件 {filename}。")
    except Exception as e:
        print(f"写入文件时发生错误: {e}")

import os

def delete_file(file_path):
    """
    删除指定路径的文件。

    参数:
    file_path (str): 要删除的文件路径。

    返回:
    bool: 如果文件成功删除，则返回True；否则返回False。
    """
    try:
        if os.path.exists(file_path):
            os.remove(file_path)
            print(f"文件 {file_path} 已删除")
            return True
        else:
            print(f"文件 {file_path} 不存在")
            return False
    except Exception as e:
        print(f"删除文件时发生错误: {e}")
        return False





def get_working_days(start_date, end_date):
    # 初始化中国的节假日
    cn_holidays = holidays.China(years=range(start_date.year, end_date.year + 1))
    # 初始化工作日列表
    working_days = []
    # 遍历开始日期到结束日期中的每一天
    current_date = start_date
    while current_date <= end_date:
        # 检查当前日期是否是周末（星期六或星期日）
        if current_date.weekday() < 5:  # 星期一到星期五的weekday()是0到4
            # 检查当前日期是否是节假日
            if current_date not in cn_holidays:
                # 如果当前日期是工作日，则添加到列表中
                working_days.append(current_date)
        # 移动到下一天
        current_date += datetime.timedelta(days=1)
    return working_days

def concurrent_http_requests(urls,max_workers=20):
    """
    并发发送HTTP请求并返回结果。

    :param urls: 要发送请求的URL列表。
    :param max_workers: 线程池中的最大线程数，默认为5。
    :return: 一个包含(url, response_data)元组的列表，其中response_data是响应的JSON数据或错误信息。
    """
    def fetch_url(url):
        try:
            response = requests.get(url)
            response.raise_for_status()  # 检查响应状态码是否为200
            return url, response.json()  # 返回URL和响应的JSON数据
        except requests.RequestException as e:
            return url, {'error': str(e)}  # 返回URL和错误信息

    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_url = {executor.submit(fetch_url, url): url for url in urls}
        for future in as_completed(future_to_url):
            url = future_to_url[future]
            try:
                result = future.result()
                results.append(result)
            except Exception as e:
                results.append((url, {'error': str(e)}))

    return results



# 获取某一天的龙虎榜数据
# 1. 获取个股总数
# 2. 获取每页数据
def get_longhubang_data(date,REnd):
    raws_hs = []
    raws_zf = []
    urls = []
    # 获取个股总数
    url = "https://apphis.longhuvip.com/w1/api/index.php?Order=1&a=HisRankingInfo_W8&st=34&c=HisStockRanking&PhoneOSNew=1&RStart=0925&DeviceID=037520ec-5c84-34a1-8d7a-813a91437308&VerSion=5.17.0.0&Isst=1&apiv=w38&Type=9&FilterMotherboard=0&Filter=0&Ratio=6&FilterBJS=0&FilterTIB=0&FilterGem=0&index=0&Date="+date+"&REnd="+REnd+"&"
    response = requests.get(url)
    if response.status_code == 200:
        json_data = response.json()
        page_size = 30
        total = json_data.get("Count")
        page_num = math.ceil(total / page_size)
        print(f"成功获取当日个股总数：{total},url:{url}")

        # 获取每页数据
        for i in range(page_num):
            url = "https://apphis.longhuvip.com/w1/api/index.php?Order=1&a=HisRankingInfo_W8&c=HisStockRanking&PhoneOSNew=1&RStart=0925&DeviceID=037520ec-5c84-34a1-8d7a-813a91437308&VerSion=5.17.0.0&Isst=1&apiv=w38&Type=9&FilterMotherboard=0&Filter=0&Ratio=6&FilterBJS=0&FilterTIB=0&FilterGem=0&st="+str(page_size)+"&index="+str(i*page_size)+"&Date=" + date + "&REnd=" + REnd + "&"
            urls.append(url)
        # 并发处理多个请求
        responses = concurrent_http_requests(urls)
        # 处理返回的数据并写入本地文件中
        for url,data in responses:
            list = data.get("list")
            # 组装每行数据
            for stock_info in list:
                market = get_tdx_market_code(stock_info[0])
                code = stock_info[0];
                huan_shou = stock_info[8]
                zhang_fu = stock_info[6]
                raw_hs = f"{market}|{code}|{date.replace('-', '')}|{huan_shou}"
                raw_zf = f"{market}|{code}|{date.replace('-', '')}|{zhang_fu}"
                raws_hs.append(raw_hs)
                raws_zf.append(raw_zf)
        write_list_to_file(raws_hs, f"E:/001-temp/通达信导入文件/实际换手/{REnd}换手.txt")
        write_list_to_file(raws_zf, f"E:/001-temp/通达信导入文件/实际换手/{REnd}涨幅.txt")
        print(f"完成一天数据请求，股票数据{len(raws_hs)}个")
    else:
        # 请求失败时打印状态码和错误信息
        print(f"Failed to retrieve data. Status code: {response.status_code}")
        print(f"Error message: {response.text}")


if __name__ == '__main__':
    """
        created 2025-01-11
        功能：生成通达信可导入文件
    """
    start_date = datetime.date(2024, 11, 1)
    end_date = datetime.date(2025, 1, 11)
    working_days = get_working_days(start_date, end_date)

    REnds = ["0935","0940","0945","1000"]
    for REnd in REnds:
        # 先删除文件，防止重复
        delete_file(f"E:/001-temp/通达信导入文件/实际换手/{REnd}换手.txt")
        delete_file(f"E:/001-temp/通达信导入文件/实际换手/{REnd}涨幅.txt")
        for day in working_days:
            print(f"{day}开始=============")
            get_longhubang_data(day.strftime('%Y-%m-%d'), REnd)
            print(f"{day}结束=============")

    print("end...")
